﻿namespace FFF.Test.Application.PublicService.AppService.Wx.WxUser
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Abp.Application.Services;
    using Abp.Dependency;
    using FFF.Test.Application.AppServices;
    using FFF.Test.Application.PublicService.AppService.Wx.Pay.Dto;
    using Senparc.Weixin;
    using Senparc.Weixin.TenPay;
    using Senparc.Weixin.TenPay.V3;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    using Senparc.Weixin.MP.AdvancedAPIs.OAuth;
    using Microsoft.AspNetCore.Http;
    using Senparc.Weixin.MP.AdvancedAPIs;
    using Senparc.Weixin.MP;
    using Senparc.CO2NET.Extensions;
    using Abp.UI;
    using Abp.ObjectMapping;
    using FFF.Test.Application.Repositories.WX;
    using FFF.Test.Entity.WX.Dto;
    using FFF.Test.Util.Consts;
    using Senparc.Weixin.MP.Helpers;

    /// <summary>
    /// 微信用户接口
    /// </summary>
    public interface IWxUserAppService : IApplicationService
    {
        /// <summary>
        /// 微信网页授权
        /// </summary>
        /// <param name="code">用户的code</param>
        /// <param name="state">状态标志</param>
        /// <param name="returnUrl">返回的URL</param>
        /// <returns>用户信息</returns>
        Task<OAuthUserInfo> UserInfoCallback(string code, string state, string returnUrl);

        /// <summary>
        /// 微信网页授权
        /// </summary>
        /// <param name="returnUrl">返回的URL</param>
        void WxAuthor(string returnUrl);

        /// <summary>
        /// 获取微信jssdk需要填写的信息
        /// </summary>
        /// <param name="url">页面的地址</param>
        /// <returns>返回jssdk信息</returns>
        Task<JsSdkUiPackage> GetJsdkPackage(string url);
    }

    /// <summary>
    /// 微信支付接口（p3版本）
    /// </summary>
    [YdmApiVersionAttribute(Version = "My")]
    public class WxUserAppService : IWxUserAppService
    {
        //下面换成账号对应的信息，也可以放入web.config等地方方便配置和更换
        private readonly string _appId = Config.SenparcWeixinSetting.WeixinAppId; //与微信公众账号后台的AppId设置保持一致，区分大小写。
        private readonly string _appSecret = Config.SenparcWeixinSetting.WeixinAppSecret; //与微信公众账号后台的AppId设置保持一致，区分大小写。

        /// <summary>
        ///  依赖注入容器
        /// </summary>
        private readonly IIocResolver _iocResolver;

        /// <summary>
        /// Initializes a new instance of the <see cref="WxUserAppService"/> class.
        /// 构造方法
        /// </summary>
        /// <param name="iocResolver">依赖注入容器</param>
        public WxUserAppService(IIocResolver iocResolver)
        {
            this._iocResolver = iocResolver;
        }

        /// <summary>
        /// 微信网页授权 http://core.yudaming.cn/api/services/app/WxUser/WxAuthor?returnUrl=https://www.baidu.com/
        /// </summary>
        /// <param name="returnUrl">返回的URL</param>
        [HttpGet]
        [AllowAnonymous]
        public void WxAuthor(string returnUrl)
        {
            var httpContext = this._iocResolver.Resolve<IHttpContextAccessor>().HttpContext;

            //var request = httpContext.Request;
            //string domain = request.Scheme + "://" + request.Host.Value;

            //此页面引导用户点击授权
            string url =
                            OAuthApi.GetAuthorizeUrl(
                            this._appId,
                             $"{AppConfigConsts.AppDomain}/api/services/app/WxUser/UserInfoCallback?returnUrl=" + returnUrl.UrlDecode().UrlEncode(),
                             "test",
                             OAuthScope.snsapi_userinfo);
            httpContext.Response.Redirect(url);
        }

        /// <summary>
        /// 微信网页授权
        /// </summary>
        /// <param name="code">用户的code</param>
        /// <param name="state">状态标志</param>
        /// <param name="returnUrl">返回的URL</param>
        /// <returns>小程序</returns>
        [HttpGet]
        [AllowAnonymous]
        public async Task<OAuthUserInfo> UserInfoCallback(string code, string state, string returnUrl)
        {
            if (string.IsNullOrEmpty(code))
            {
                throw new UserFriendlyException("用户拒绝了授权");
            }

            OAuthAccessTokenResult result = OAuthApi.GetAccessToken(this._appId, this._appSecret, code);

            OAuthUserInfo userInfo = OAuthApi.GetUserInfo(result.access_token, result.openid);
            var objectMapper = this._iocResolver.Resolve<IObjectMapper>();
            var wxUserRes = this._iocResolver.Resolve<IWXUserInfoRepository>();
            var httpContext = this._iocResolver.Resolve<IHttpContextAccessor>().HttpContext;

            var wsUserEntity = await wxUserRes.FirstOrDefaultAsync(x => x.Openid == userInfo.unionid);
            if (wsUserEntity == null)
            {
                WXUserInfoCreateInputDto createInput = new WXUserInfoCreateInputDto()
                {
                    Openid = userInfo.openid,
                    Unionid = userInfo.unionid,
                    NickName = userInfo.nickname,
                    City = userInfo.city,
                    Country = userInfo.country,
                    HeadImgurl = userInfo.headimgurl,
                    Sex = userInfo.sex,
                    Province = userInfo.province
                };

                await wxUserRes.CreateByDtoAsync(createInput);
            }

            returnUrl = returnUrl + $"{(returnUrl.Contains("?") ? "&" : " ? ")}openId={userInfo.openid}";

            //  httpContext.Response.Redirect(returnUrl);
            return userInfo;
        }

        /// <summary>
        /// 获取微信jssdk信息
        /// </summary>
        /// <param name="url">页面的地址</param>
        /// <returns>返回jssdk信息</returns>
        [HttpPost]
        [Authorize(Roles = "admin")]
        public async Task<JsSdkUiPackage> GetJsdkPackage(string url)
        {
            url = url.UrlDecode(); // 解码前端需要加码
            var jssdkUiPackage = JSSDKHelper.GetJsSdkUiPackage(this._appId, this._appSecret, url);
            return await Task.FromResult(jssdkUiPackage);
        }
    }

}
